package function;

import java.io.File;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Notice {
	private String code;//公告编号
	private String manager;//发布此公告的管理员
	private String content;//公告内容

	public Notice(String code, String manager, String content) {
		this.code = code;
		this.manager = manager;
		this.content = content;
	}

	public Notice() {
		this.code = null;
		this.manager = null;
		this.content = null;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getManager() {
		return manager;
	}

	public void setManager(String manager) {
		this.manager = manager;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}
	//只打印编号和管理员
	public ArrayList<String> display() {
		ArrayList<String> g = getAllNotices();
		return g;
	}

	public boolean add() {
		boolean a = addNotices(this);
		return a;
	}

	public boolean delete(String text) {
		boolean d = deleteNotice(text);
		return d;
	}

	public boolean modify(String text) {
		boolean m = modifyNotice(text, this);
		return m;
	}
	/*通过传入的text（text为发布该公告的管理员的id和username）返回对应的公告对象，
	text对应gui界面按钮组后显示的内容
	通过看界面显示的内容即可理解text的含义和作用
	*/
	public Notice find(String text) {
		Notice n = findNotice(this, text);
		return n;
	}
	/*查询公告，text对应gui界面用户选中的JRadioButton的text内容
	 * 根据用户选择的JRadioButton打印出此公告的信息 
	 */
	public String inquire(String text) {
		String i=inquireNotice(text);
		return i;
	}
    //通过ArrayList打印出所有公告的信息
	public ArrayList<String> getAll() {
		ArrayList<String> list = displayAllNotices();
		return list;
	}
	//保存公告信息的xml文件路径
	String xmlPath = "notice.xml";
	//同Scenic类的getAllScenics方法
	private ArrayList<String> getAllNotices() {
		ArrayList<String> list = new ArrayList<String>();
		// 创建文件工厂实例
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 如果创建的解析器在解析XML文档时必须删除元素内容中的空格，则为true，否则为false
		dbf.setIgnoringElementContentWhitespace(true);

		try {
			/*
			 * 创建文件对象
			 */
			DocumentBuilder db = dbf.newDocumentBuilder();// 创建解析器，解析XML文档
			Document doc = db.parse(xmlPath); // 使用dom解析xml文件
			/*
			 * 遍历列表，进行XML文件的数据提取
			 */
			// 根据节点名称来获取所有相关的节点
			NodeList sonlist = doc.getElementsByTagName("notice");
			for (int i = 0; i < sonlist.getLength(); i++) // 循环处理对象
			{
				// 节点属性的处理
				Element son = (Element) sonlist.item(i);
				NodeList elements = son.getElementsByTagName("code");
				NodeList elements2 = son.getElementsByTagName("manager");
				Node node = elements.item(0);
				Node node2 = elements2.item(0);
				if (node.getNodeType() == Node.ELEMENT_NODE && node2.getNodeType() == Node.ELEMENT_NODE) {
					String value = node.getFirstChild().getNodeValue();
					String value2 = node2.getFirstChild().getNodeValue();
					list.add(value + "   " + value2);
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return list;
	}
	//同Scenic类的addScenic方法，详情参见Scenic类的addScenic方法
	private boolean addNotices(Notice notice) {
		// 创建文件工厂实例，用于解析xml文件
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(false);

		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			// 创建Document对象
			Document xmldoc = db.parse(xmlPath);

			// 根据节点名称来获取所有相关的节点
			NodeList sonlist = xmldoc.getElementsByTagName("notice");
			for (int i = 0; i < sonlist.getLength(); i++) // 循环处理对象
			{
				// 节点属性的处理
				Element son = (Element) sonlist.item(i);
				NodeList elements;
				elements = son.getElementsByTagName("code");
				Node node0 = elements.item(0);

				if (node0.getNodeType() == Node.ELEMENT_NODE) {
					String value0 = node0.getFirstChild().getNodeValue();
					if (value0.equals(notice.getCode())) {
						return false;
					}
				}
			}

			// 获取根节点
			Element root = xmldoc.getDocumentElement();
			// 创建节点son
			Element son = xmldoc.createElement("notice");

			Element code = xmldoc.createElement("code");
			code.setTextContent(notice.getCode());
			son.appendChild(code);

			Element manager = xmldoc.createElement("manager");
			manager.setTextContent(notice.getManager());
			son.appendChild(manager);

			Element content = xmldoc.createElement("content");
			content.setTextContent(notice.getContent());
			son.appendChild(content);

			// 把son添加到根节点中
			root.appendChild(son);

			// 保存到xml文件
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer former = factory.newTransformer();
			former.setOutputProperty(OutputKeys.VERSION, "1.0");
			former.setOutputProperty(OutputKeys.INDENT, "yes");// 缩进
			former.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			former.transform(new DOMSource(xmldoc), new StreamResult(new File(xmlPath)));

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return true;
	}
	//同Scenic类的deleteScenic方法，详情参见Scenic类的deleteScenic方法
	private boolean deleteNotice(String text) {
		String c[] = text.split(" ");
		String code = c[0];

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(true);

		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document xmldoc = db.parse(xmlPath);
			// 获取根节点
			Element root = xmldoc.getDocumentElement();
			Element son = (Element) selectSingleNode("/noticeList/notice/code[text()='" + code + "']/parent::*", root);

			// 删除该节点
			root.removeChild(son);
			// 保存到xml文件
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer former = factory.newTransformer();
			former.setOutputProperty(OutputKeys.VERSION, "1.0");
			former.setOutputProperty(OutputKeys.INDENT, "yes");// 缩进
			former.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			former.transform(new DOMSource(xmldoc), new StreamResult(new File(xmlPath)));
			return true;
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return false;
		}
	}
	//同Scenic类的findScenic方法，详情参见Scenic类的findScenic方法
	private Notice findNotice(Notice notice, String text) {
		String c[] = text.split(" ");
		String code = c[0];

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(true);

		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document xmldoc = db.parse(xmlPath);
			// 获取根节点
			Element root = xmldoc.getDocumentElement();
			//构建str用于查询满足特定条件的结点
			String str = "/noticeList/notice/code[text()='" + code + "']/parent::*";
			//将str作为参数传入selectSingleNode方法查找满足条件的结点
			Element son = (Element) selectSingleNode(str, root);

			for (Node node = son.getFirstChild(); node != null; node = node.getNextSibling()) {
				// 判断是否为元素节点
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					String name0 = node.getNodeName();
					String value = node.getFirstChild().getNodeValue();
					if ("code".equals(name0)) {
						notice.setCode(value);
					} else if ("manager".equals(name0)) {
						notice.setManager(value);
					} else {
						notice.setContent(value);
					}
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return notice;
	}
	//同Scenic类的inquireScenic方法，详情参见Scenic类的inquireScenic方法
	private String inquireNotice(String text) {
		String c[] = text.split(" ");
		String code = c[0];

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 如果创建的解析器在解析XML文档时必须删除元素内容中的空格，则为true，否则为false
		dbf.setIgnoringElementContentWhitespace(true);

		String information = "<html><body>";
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();// 创建解析器，解析XML文档
			Document doc = db.parse(xmlPath); // 使用dom解析xml文件

			// 根据节点名称来获取所有相关的节点
			NodeList sonlist = doc.getElementsByTagName("notice");
			for (int i = 0; i < sonlist.getLength(); i++) // 循环处理对象
			{
				// 节点属性的处理
				Element son = (Element) sonlist.item(i);
				NodeList elements;
				elements = son.getElementsByTagName("code");
				Node node0 = elements.item(0);

				if (node0.getNodeType() == Node.ELEMENT_NODE) {
					String value0 = node0.getFirstChild().getNodeValue();
					if (value0.equals(code)) {
						for (Node node = son.getFirstChild(); node != null; node = node.getNextSibling()) {
							// 判断是否为元素节点
							if (node.getNodeType() == Node.ELEMENT_NODE) {
								String name = node.getNodeName();
								String value = node.getFirstChild().getNodeValue();
								information += (name + ":" + value + "<br/>");
							}
						}
					}
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		information += "</body></html>";
		return information;
	}
	//同Scenic类的modifyScenic方法，详情参见Scenic类的modifyScenic方法
	private boolean modifyNotice(String text, Notice notice) {
		String c[] = text.split(" ");
		String code = c[0];

		// 创建文件工厂实例
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(true);

		try {
			// 从XML文档中获取DOM文档实例
			DocumentBuilder db = dbf.newDocumentBuilder();
			// 获取Document对象
			Document xmldoc = db.parse(xmlPath);
			
			// 获取根节点
			Element root = xmldoc.getDocumentElement();
			//构建str用于查询满足特定条件的结点
			String str = "/noticeList/notice/code[text()='" + code + "']/parent::*";
			//将str作为参数传入selectSingleNode方法查找满足条件的结点
			Element per = (Element) selectSingleNode(str, root);

			per.getElementsByTagName("code").item(0).setTextContent(notice.getCode());
			per.getElementsByTagName("manager").item(0).setTextContent(notice.getManager());
			per.getElementsByTagName("content").item(0).setTextContent(notice.getContent());
			// 保存到xml文件
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer former = factory.newTransformer();
			former.setOutputProperty(OutputKeys.VERSION, "1.0");
			former.setOutputProperty(OutputKeys.INDENT, "yes");// 缩进
			former.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			former.transform(new DOMSource(xmldoc), new StreamResult(new File(xmlPath)));
			return true;
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return false;
		}
	}
	/*
	 * 由于文本文件均采用xml格式，selectSingleNode方法在对四个xml文件进行操作的类
	 * Manager类，Notice类，Edge类，Scenic类中均有
	 * 此方法用于查询结点（xml为树型结构），且此方法只返回单个结点
	 */
	private static Node selectSingleNode(String express, Element source) {
		// 创建XPath工厂
		XPathFactory xpathFactory = XPathFactory.newInstance();
		// 创建XPath对象
		XPath xpath = xpathFactory.newXPath();

		Node result = null;
		try {
			//计算XPath表达式
			result = (Node) xpath.evaluate(express, source, XPathConstants.NODE);
		} catch (XPathExpressionException e) {
			System.out.println(e.getMessage());
		}
		//返回目标结点
		return result;
	}
	
	public int getTotalNumber() {
		int i = 0;
		// 创建文件工厂实例
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 如果创建的解析器在解析XML文档时必须删除元素内容中的空格，则为true，否则为false
		dbf.setIgnoringElementContentWhitespace(true);
		try {
			// 创建文件对象
			DocumentBuilder db = dbf.newDocumentBuilder();// 创建解析器，解析XML文档
			Document doc = db.parse(xmlPath); // 使用dom解析xml文件
			// 遍历列表，进行XML文件的数据提取
			// 根据节点名称来获取所有相关的节点
			NodeList sonlist = doc.getElementsByTagName("notice");
			i = sonlist.getLength();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return i;
	}
	//同Scenic类的getAllScenics方法，详情参见Scenic类的getAllScenics方法
    public ArrayList<String> displayAllNotices() {
        ArrayList<String> list = new ArrayList<String>();
        String xmlPath = "notice.xml";
        // 创建文件工厂实例
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 如果创建的解析器在解析XML文档时必须删除元素内容中的空格，则为true，否则为false
        dbf.setIgnoringElementContentWhitespace(true);
        
        try {
            /*
             * 创建文件对象
             */
            DocumentBuilder db = dbf.newDocumentBuilder();// 创建解析器，解析XML文档
            Document doc = db.parse(xmlPath); // 使用dom解析xml文件
            /*
             * 遍历列表，进行XML文件的数据提取
             */
            // 根据节点名称来获取所有相关的节点
            NodeList sonlist = doc.getElementsByTagName("notice");
            for (int i = 0; i < sonlist.getLength(); i++) // 循环处理对象
            {
                // 节点属性的处理
                Element son = (Element) sonlist.item(i);
                NodeList elements1 = son.getElementsByTagName("code");
                NodeList elements2 = son.getElementsByTagName("manager");
                NodeList elements3 = son.getElementsByTagName("content");
                Node node1 = elements1.item(0);
                Node node2 = elements2.item(0);
                Node node3 = elements3.item(0);
                if (node1.getNodeType() == Node.ELEMENT_NODE && node2.getNodeType() == Node.ELEMENT_NODE) {
                    String value1 = node1.getFirstChild().getNodeValue();
                    String value2 = node2.getFirstChild().getNodeValue();
                    String value3 = node3.getFirstChild().getNodeValue();
                    String information="<html><body>"+value1 + "  " + value2+"<br/>"+value3+"<br/>";
                    information += "-----------------------------------------<br/>";
                    list.add(information);
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return list;
    }
}
